package com.bwie.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReUtil;
import com.bwie.domain.BookExport;
import com.bwie.domain.ResourceRecommendation;
import com.bwie.service.ImportService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.springframework.data.keyvalue.repository.support.SimpleKeyValueRepository;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @className: importResourceExcel
 * @Description: TODO
 * @version: v1.８.0
 * @author: GONGWENXUE
 * @date: 2025/11/10 16:52
 */
@Service
@Component
@Slf4j
public class Export implements ImportService {
    // 必填字段（Excel表头）
    private static final List<String> REQUIRED_FIELDS = Arrays.asList(
            "题名", "文献类型", "载体", "学科"
    );

    // ISSN/ISBN类字段（至少填一个）
    private static final List<String> ISSN_ISBN_FIELDS = Arrays.asList(
            "PISSN", "EISSN", "PISBN", "EISBN"
    );

    // 出版年正则（4位阿拉伯数字）
    private static final String PUBLISH_YEAR_REGEX = "^[0-9]{4}$";
    private SimpleKeyValueRepository recommendationRepository;

    /**
     * 实体类数据校验（按规则校验）
     * @param  bookExport
     * @param rowNum 数据行号（用于错误提示）
     * @return 校验错误信息（null表示校验通过）
     */
    private String validateEntity(BookExport bookExport, int rowNum) {
        // 1. 校验必填字段
        if (bookExport.getTitles() == null || bookExport.getTitles().isEmpty()) {
            return String.format("第%d行：'题名'为必填字段，不能为空", rowNum);
        }
        if (bookExport.getDocumentType() == null || bookExport.getDocumentType().isEmpty()) {
            return String.format("第%d行：'文献类型'为必填字段，不能为空", rowNum);
        }
        if (bookExport.getCarrier() == null || bookExport.getCarrier().isEmpty()) {
            return String.format("第%d行：'载体'为必填字段，不能为空", rowNum);
        }
        if (bookExport.getSubject() == null || bookExport.getSubject().isEmpty()) {
            return String.format("第%d行：'学科'为必填字段，不能为空", rowNum);
        }

        // 2. 校验ISSN/ISBN字段（至少填一个）
        boolean hasIssnIsbn = (bookExport.getPISBN() != null && !bookExport.getPISSN().isEmpty())
                || (bookExport.getEISSN() != null && !bookExport.getEISSN().isEmpty())
                || (bookExport.getPISBN() != null && !bookExport.getPISBN().isEmpty())
                || (bookExport.getELSBN() != null && !bookExport.getELSBN().isEmpty());
        if (!hasIssnIsbn) {
            return String.format("第%d行：PISSN、EISSN、PISBN、EISBN至少填写一个", rowNum);
        }

        // 3. 校验出版年格式
        Integer publishYear = bookExport.getPublishYear();
        if (publishYear != null) {
            String yearStr = String.valueOf(publishYear);
            if (!ReUtil.isMatch(PUBLISH_YEAR_REGEX, yearStr)) {
                return String.format("第%d行：出版年需填写4位小写阿拉伯数字（例：2018），当前值：%d", rowNum, publishYear);
            }
            // 额外校验年份合理性（1900-当前年份）
            int currentYear = Calendar.getInstance().get(Calendar.YEAR);
            if (publishYear < 1900 || publishYear > currentYear) {
                return String.format("第%d行：出版年需在1900-%d之间，当前值：%d", rowNum, currentYear, publishYear);
            }
        }

        // 4. 校验单选字段（文献类型、载体）
        String docTypeMsg = validateSingleSelectField("documentType", bookExport.getDocumentType(), rowNum);
        if (docTypeMsg != null) return docTypeMsg;

        String carrierMsg = validateSingleSelectField("carrier", bookExport.getCarrier(), rowNum);
        if (carrierMsg != null) return carrierMsg;

        // 5. 校验多选字段（学科）
        String subjectMsg = validateMultipleSelectField("subject", bookExport.getSubject(), rowNum);
        if (subjectMsg != null) return subjectMsg;

        // 所有校验通过
        return null;
    }

    private String validateMultipleSelectField(String subject, String subject1, int rowNum) {
       return null;
    }

    private String validateSingleSelectField(String documentType, String documentType1, int rowNum) {

        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BookExport importResourceExcel(MultipartFile file) {
        BookExport bookExport = new BookExport();
        List<ResourceRecommendation> validDataList = new ArrayList<>();

        // 1. 校验文件格式
        if (!file.getOriginalFilename().endsWith(".xlsx")) {
            return bookExport;
        }

        // 2. 读取Excel文件
        try (InputStream inputStream = file.getInputStream()) {
            Workbook workbook = WorkbookFactory.create(inputStream);
            Sheet sheet = workbook.getSheetAt(0); // 读取第一个工作表
            if (sheet == null) {
                return bookExport;
            }

            // 3. 校验表头
            Row headerRow = sheet.getRow(0);
            if (headerRow == null) {
                return bookExport;
            }
            Map<Integer, String> headerMap = getHeaderMap(headerRow);
            if (!validateHeader(headerMap)) {
                return bookExport;
            }

            // 4. 读取数据并逐行校验
            int lastRowNum = sheet.getLastRowNum();
            if (lastRowNum < 1) {
                return bookExport;
            }

            for (int rowNum = 1; rowNum <= lastRowNum; rowNum++) {
                Row dataRow = sheet.getRow(rowNum);
                if (dataRow == null) continue;

                // 逐行校验并转换为实体
                ResourceRecommendation recommendation = convertRowToEntity(dataRow, headerMap);
                String validateMsg = validateEntity(recommendation, rowNum + 1); // 行号从1开始展示
                if (validateMsg != null) {
                    bookExport.setStatus("fail");
                    bookExport.setErrorMsg(validateMsg);
                    bookExport.setErrorRow(rowNum + 1);
                    return bookExport;
                }

                validDataList.add(recommendation);
            }

            // 5. 保存有效数据到数据库
            if (CollUtil.isNotEmpty(validDataList)) {
                validDataList.forEach(data -> {
                    data.setImportTime(new Date());
                    data.setDataStatus(0); // 0-待查重
                });
                List<ResourceRecommendation> savedList = (List<ResourceRecommendation>) recommendationRepository.saveAll(validDataList);

                // 6. 组装返回结果
                bookExport.setStatus("success");
                bookExport.setSuccessCount(savedList.size());
                bookExport.setDataIds(savedList.stream()
                        .map(ResourceRecommendation::getId)
                        .collect(Collectors.toList()));
                log.info("资源荐购数据导入成功，共{}条数据", savedList.size());
            } else {
                bookExport.setStatus("fail");
                bookExport.setErrorMsg("Excel文件无有效数据，请检查数据格式");
            }

        } catch (IOException e) {
            log.error("读取Excel文件异常", e);
            bookExport.setStatus("fail");
            bookExport.setErrorMsg("文件读取失败，可能文件损坏或格式错误");
        } catch (Exception e) {
            log.error("资源导入校验异常", e);
            bookExport.setStatus("fail");
            bookExport.setErrorMsg("系统异常，请稍后重试");
        }

        return bookExport;
    }

    private String validateEntity(ResourceRecommendation recommendation, int i) {
        return null;
    }

    private ResourceRecommendation convertRowToEntity(Row dataRow, Map<Integer, String> headerMap) {
        return null;
    }

    private Map<Integer, String> getHeaderMap(Row headerRow) {
        return (Map<Integer, String>) headerRow;
    }


    /**
     * 校验表头是否完整
     */
    private boolean validateHeader(Map<Integer, String> headerMap) {
        return REQUIRED_FIELDS.stream().allMatch(headerMap.values()::contains)
                && ISSN_ISBN_FIELDS.stream().allMatch(headerMap.values()::contains);
    }

    /**
     * 获取参数类型的中文名称（用于错误提示）
     */
    private String getParamTypeName(String paramType) {
        switch (paramType) {
            case "documentType":
                return "文献类型";
            case "carrier":
                return "载体";
            case "subject":
                return "学科";
            default:
                return paramType;
        }
    }

}
